package pl.edu.mimuw.mas.agent.behaviour.hunting.dog;

import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pl.edu.mimuw.mas.agent.DogAgent;
import pl.edu.mimuw.mas.agent.behaviour.ServerBehaviour;
import pl.edu.mimuw.mas.message.PositionMessage;
import pl.edu.mimuw.mas.message.ScareFactorMessage;
import pl.edu.mimuw.mas.util.Position;
import pl.edu.mimuw.mas.util.PositionHelper;

public class ScareFactorServerBehaviour extends ServerBehaviour {
	
	private static final long serialVersionUID = 4987333098956054233L;
	
	protected final Logger logger = LoggerFactory.getLogger(getClass());

	public ScareFactorServerBehaviour(DogAgent a) {
		super(a);

		MessageTemplate mt = MessageTemplate.and(
				MessageTemplate.MatchConversationId(DogAgent.SCARE_FACTOR_CONV),
				MessageTemplate.MatchPerformative(ACLMessage.REQUEST)
				);
		setMessageTemplate(mt);
	}

	@Override
	public boolean doAction(ACLMessage msg, ACLMessage reply) throws UnreadableException, IOException {
		DogAgent a = (DogAgent) myAgent;
		
		if (!a.isLeader()) { // czyli zmienil sie status tego agenta i juz nie jest liderem
			return false;
		}
		
		Position avgDogGroupPosition = a.getAvgGroupPosition();
		Position deerPosition = PositionHelper.getDeerPosition();
		
		PositionMessage pm = (PositionMessage) msg.getContentObject();
		
		if (pm != null) {
			Position avgHunterGroupPosition = new Position(pm.x, pm.y);
			double groupsDist = PositionHelper.getDistance(avgDogGroupPosition, avgHunterGroupPosition);
			double deerDogDist = PositionHelper.getDistance(avgDogGroupPosition, deerPosition);
			double deerHunterDist = PositionHelper.getDistance(avgHunterGroupPosition, deerPosition); 
			
			double factor = (groupsDist * groupsDist) / ((deerDogDist * deerDogDist) + (deerHunterDist * deerHunterDist));
			
			reply.setContentObject(new ScareFactorMessage(a.getAID(), factor));
			reply.setPerformative(ACLMessage.INFORM);
			
			return true;
		}		
		
		return false;
	}

}
